Skip to content

Implement lazy directives for Ramble - #1756

Open
linsword13 wants to merge 1 commit into
Ramble-Project:developfrom
linsword13:lazy-directives
Open

linsword13 wants to merge 1 commit into
Ramble-Project:developfrom
linsword13:lazy-directives

Conversation

@linsword13

Copy link
Copy Markdown
Collaborator

This is inspired by Spack's lazy directive (spack/spack#51881).

  • Add in the dict descriptor (as a non-data descriptor) to support the lazy initiailization
  • Remove the convert_class_attributes since now the lazy execution allows us to perform copy on first access
  • Update the various directives to support the new semantics. Specifically, it now requires listing out all mutated dicts of a directive
  • Also unify the various language meta directives, so now they are all essentially DirectiveMeta
  • Update the mirror test since before it implicitly relied on the mutation happening both at the class and the instance level

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors Ramble's directive system to support lazy evaluation of directives upon first access using a new DirectiveDictDescriptor descriptor. It removes the need for explicit class-to-instance attribute conversion and updates various base classes to use DirectiveMeta directly as their metaclass. Additionally, comprehensive tests are added to verify lazy evaluation, inheritance, and attribute isolation. The review feedback highlights a critical issue where instance-level modifications to these lazily evaluated directive dictionaries would be lost during cloning or copying. It is recommended to dynamically copy all evaluated directive dictionaries from self.__dict__ to the cloned or copied instances in both ApplicationBase.clone() and ObjectMixin.copy().

Comment thread var/ramble/repos/builtin/base_classes/application-base/base_class.py Outdated
Comment thread var/ramble/repos/builtin/base_classes/object-mixin/base_class.py
@ramble-pr-bot

ramble-pr-bot Bot commented Sep 1, 2026

Copy link
Copy Markdown

Ramble Performance Test Metrics

Results produced with commit: 3377deb

Test Name Outcome Duration (s) Most Recent Run (s) Last 5 Avg (s)
test_analyze_large_file passed 1.0483 1.0590 (b7a264f) 1.0648
test_large_template_expansion passed 1.1838 1.1979 (b7a264f) 1.3086
test_many_experiments passed 27.0491 23.4773 (b7a264f) 24.0185
test_many_objects_defaults passed 14.6088 12.3728 (b7a264f) 12.4969
test_matrix_filter_perf passed 0.9941 1.0663 (b7a264f) 1.1014

@codecov

codecov Bot commented Sep 1, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.78870% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 94.08%. Comparing base (6d999da) to head (e9a802e).
⚠️ Report is 3 commits behind head on develop.

Files with missing lines Patch % Lines
lib/ramble/ramble/language/language_base.py 94.23% 9 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #1756      +/-   ##
===========================================
+ Coverage    94.07%   94.08%   +0.01%     
===========================================
  Files          370      370              
  Lines        37399    37554     +155     
===========================================
+ Hits         35182    35333     +151     
- Misses        2217     2221       +4     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@linsword13

Copy link
Copy Markdown
Collaborator Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors Ramble's directive system to support lazy evaluation on first access, introducing the DirectiveDictDescriptor class and removing the eager conversion of class attributes to instance attributes across all base classes. A comprehensive test suite has been added to verify lazy evaluation, inheritance, and isolation. The review feedback highlights critical inheritance issues where using getattr on classes or objects can mistakenly retrieve parent class attributes (such as evaluated directive dictionaries or preferred versions) instead of checking the subclass's own __dict__ directly, which would bypass subclass directive execution or raise incorrect errors.

Comment thread lib/ramble/ramble/language/language_base.py Outdated
Comment thread lib/ramble/ramble/language/language_base.py Outdated
Comment thread lib/ramble/ramble/language/shared_language.py Outdated
@linsword13

Copy link
Copy Markdown
Collaborator Author

/gemini review

@linsword13
linsword13 force-pushed the lazy-directives branch 2 times, most recently from 7efbad1 to 2b398d1 Compare September 3, 2026 18:29
@linsword13

Copy link
Copy Markdown
Collaborator Author

/gemini review

@linsword13
linsword13 marked this pull request as ready for review September 4, 2026 00:35

@rfbgo rfbgo left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two random questions:

  1. The bot reports a slow down from this. Is it it true? If so I think there are some places we might be able to improve perf slightly (eg optimized copies)
  2. I asked gemini to review this PR wrt "leaking" (it says it will leak). I kind of expect this is something you were already careful about, but I wanted to double check we believe this is indeed safe?

Comment thread lib/ramble/ramble/language/language_base.py Outdated
Comment thread lib/ramble/ramble/language/language_base.py
Comment thread var/ramble/repos/builtin/base_classes/object-mixin/base_class.py
Comment thread lib/ramble/ramble/language/language_base.py
@linsword13

Copy link
Copy Markdown
Collaborator Author

Two random questions:

  1. The bot reports a slow down from this. Is it it true? If so I think there are some places we might be able to improve perf slightly (eg optimized copies)
  2. I asked gemini to review this PR wrt "leaking" (it says it will leak). I kind of expect this is something you were already careful about, but I wanted to double check we believe this is indeed safe?

Great questions:

For 1. it does seem to cause a slowdown on some perf tests. One reason is that previously the directive initialization cost are part of the startup, which wasn't counted by the benchmarking. And now with the lazy init, these init times are now part of the operations that are being benchmarked. So this is more or less an accounting thing. Other factors include the more works that are needed during copy (as we can no longer rely on the class-level attributes.) I should do a more thorough analysis though to see if any improvements are possible, and at least have a better breakdown of the timing.

For 2. I did try to look for leaking, but I will do another pass to see where I missed.

@linsword13
linsword13 force-pushed the lazy-directives branch 2 times, most recently from 73a3649 to 85adeac Compare September 14, 2026 23:11
@codecov

codecov Bot commented Sep 14, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.24853% with 32 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
lib/ramble/ramble/language/language_base.py 92.46% 19 Missing ⚠️
...amble/ramble/test/language/test_lazy_directives.py 98.37% 7 Missing ⚠️
...os/builtin/base_classes/object-mixin/base_class.py 81.25% 6 Missing ⚠️

📢 Thoughts on this report? Let us know!

@linsword13
linsword13 marked this pull request as draft September 14, 2026 23:41
@linsword13
linsword13 force-pushed the lazy-directives branch 3 times, most recently from 812fa9d to bec5989 Compare September 16, 2026 21:38
Convert eager directive execution into on-demand lazy evaluation via non-data descriptors, eliminating upfront convert_class_attributes deepcopies and isolating instance mutations.

Signed-off-by: Lin Guo <linsword13@gmail.com>
@linsword13

Copy link
Copy Markdown
Collaborator Author

Two random questions:

  1. The bot reports a slow down from this. Is it it true? If so I think there are some places we might be able to improve perf slightly (eg optimized copies)
  2. I asked gemini to review this PR wrt "leaking" (it says it will leak). I kind of expect this is something you were already careful about, but I wanted to double check we believe this is indeed safe?

Great questions:

For 1. it does seem to cause a slowdown on some perf tests. One reason is that previously the directive initialization cost are part of the startup, which wasn't counted by the benchmarking. And now with the lazy init, these init times are now part of the operations that are being benchmarked. So this is more or less an accounting thing. Other factors include the more works that are needed during copy (as we can no longer rely on the class-level attributes.) I should do a more thorough analysis though to see if any improvements are possible, and at least have a better breakdown of the timing.

For 2. I did try to look for leaking, but I will do another pass to see where I missed.

The perf has been improved. The leaking should hopefully be addressed as well.

@linsword13
linsword13 marked this pull request as ready for review September 18, 2026 17:57
@rfbgo

rfbgo commented Sep 18, 2026

Copy link
Copy Markdown
Collaborator

The perf has been improved. The leaking should hopefully be addressed as well.

Awesome, thank you for being willing to take those in. I know those were none trivial changes but I think the code is stronger now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants